#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "wifi.h"
#include "common.h"

#define BUFFER_SIZE 1024
#define CONF_FILE "/reemoon/config/wpa_supplicant.conf"
#define INTERFACE "wlan0"

#define FIFO_TX_PATH "/reemoon/config/wifi_rx_fifo"
#define FIFO_RX_PATH "/reemoon/config/wifi_tx_fifo"

static int fifo_rx_fd;
static int fifo_tx_fd;

static wifi_info_t wifi_info;

static void *fifo_receive_pth(void *arg);
static void data_process(char *data, int len);
static wifi_info_t *wifi_client_status(char *status) ;


// 函数用于执行命令并返回输出
char* execute_command_get_data(const char* command) {
    FILE* pipe = popen(command, "r");
    if (!pipe) {
        reemoon_error ("popen\n");
        return NULL;
    }

    char* output = (char*)malloc(BUFFER_SIZE * sizeof(char));
    if (!output) {
        reemoon_error("malloc\n");
        pclose(pipe);
        return NULL;
    }
    memset(output, 0, BUFFER_SIZE);

    fgets(output, BUFFER_SIZE, pipe);
    pclose(pipe);

    // 去除换行符
    char* newline = strchr(output, '\n');
    if (newline) {
        *newline = '\0';
    }

    return output;
}

// 执行系统命令并返回命令执行结果
int execute_command(const char *command) {
    pid_t pid = fork();
    if (pid == -1) {
        reemoon_error ("fork\n");
        return -1;
    } else if (pid == 0) {
        // 子进程执行命令
        execl("/bin/sh", "sh", "-c", command, NULL);
        reemoon_ignore ("execl\n");
        exit(EXIT_FAILURE);
    } else {
        // 父进程等待子进程结束
        int status;
        waitpid(pid, &status, 0);
        return WEXITSTATUS(status);
    }
}

// 从配置文件中提取 SSID
char *extract_ssid(const char *conf_file) 
{
    char command[BUFFER_SIZE];
    snprintf(command, BUFFER_SIZE, "grep 'ssid=' %s | sed 's/^[[:space:]]*ssid=\"\\([^\"]*\\)\"[[:space:]]*$/\\1/'", conf_file);
    FILE *pipe = popen(command, "r");
    if (!pipe) {
        reemoon_error ("popen\n");
        return NULL;
    }

    char *ssid = (char *)malloc(BUFFER_SIZE);
    if (!ssid) {
        reemoon_error ("malloc\n");
        pclose(pipe);
        return NULL;
    }
    if (fgets(ssid, BUFFER_SIZE, pipe) == NULL) {
        free(ssid);
        pclose(pipe);
        return NULL;
    }
    // 去除换行符
    char *newline = strchr(ssid, '\n');
    if (newline) {
        *newline = '\0';
    }
    pclose(pipe);
    return ssid;
}

// 解除禁用
int wifi_unblock (void)
{
    char command[BUFFER_SIZE];
    snprintf(command, BUFFER_SIZE, "rfkill unblock wifi");
    return execute_command(command) == 0;
}

// 检查接口是否存在
int interface_exists(const char *interface) 
{
    char command[BUFFER_SIZE];
    snprintf(command, BUFFER_SIZE, "ifconfig %s > /dev/null 2>&1", interface);
    return execute_command(command) == 0;
}

// 扫描 Wi-Fi 网络并检查 SSID 是否存在
int scan_wifi(const char *interface, const char *ssid) 
{
    char command[BUFFER_SIZE];
    snprintf(command, BUFFER_SIZE, "iwlist %s scan | grep '%s'", interface, ssid);
    FILE *pipe = popen(command, "r");
    if (!pipe) {
        reemoon_error ("popen\n");
        return 0;
    }
    char buffer[BUFFER_SIZE];
    int found = fgets(buffer, BUFFER_SIZE, pipe) != NULL;
    pclose(pipe);
    return found;
}

int wifi_client_connect(void) 
{
    // 从配置文件中提取 SSID
    char *ssid = extract_ssid(CONF_FILE);
    if (!ssid || strlen(ssid) == 0) {
        reemoon_error ("无法从 %s 中提取 SSID, 退出.\n", CONF_FILE);
        free(ssid);
        return 1;
    }
    
    // 解除禁用
    if (!wifi_unblock()) {
        reemoon_error ("%s 解除禁用失败.\n", INTERFACE);
        free(ssid);
        return 1;
    }

    execute_command("ifconfig "INTERFACE" up");
    
    // 检查 wlan0 接口是否存在
    if (!interface_exists(INTERFACE)) {
        reemoon_error ("%s 接口不存在, 退出.\n", INTERFACE);
        free(ssid);
        return 1;
    }
    
    char status = -1;
    wifi_client_status(&status);
    reemoon_ignore ("wifi status: %d\n", status);
    if (status == 0)
        return 0;


    // 检查 wlan0 接口是否存在
    if (!interface_exists(INTERFACE)) {
        reemoon_error ("%s 接口不存在, 退出.\n", INTERFACE);
        free(ssid);
        return 1;
    }

    // 继续执行原脚本逻辑
    execute_command("rfkill unblock wifi");
    execute_command("pkill wpa_supplicant");

    // 扫描 Wi-Fi 网络
    if (!scan_wifi(INTERFACE, ssid)) {
        reemoon_error ("未搜索到 SSID 为 %s 的 Wi-Fi 网络, 退出.\n", ssid);
        free(ssid);
        return 1;
    }

    char wpa_command[BUFFER_SIZE];
    snprintf(wpa_command, BUFFER_SIZE, "wpa_supplicant -i %s -c %s -B", INTERFACE, CONF_FILE);
    execute_command(wpa_command);

    char ifconfig_down[BUFFER_SIZE];
    snprintf(ifconfig_down, BUFFER_SIZE, "ifconfig %s down", INTERFACE);
    execute_command(ifconfig_down);

    sleep(1);

    char ifconfig_up[BUFFER_SIZE];
    snprintf(ifconfig_up, BUFFER_SIZE, "ifconfig %s up", INTERFACE);
    execute_command(ifconfig_up);

    char udhcpc_command[BUFFER_SIZE];
    snprintf(udhcpc_command, BUFFER_SIZE, "udhcpc -i %s -R", INTERFACE);
    execute_command(udhcpc_command);

    free(ssid);
    return 0;
}

int wifi_client_disconnect() 
{
    // 从配置文件中提取 SSID
    char *ssid = extract_ssid(CONF_FILE);
    if (!ssid || strlen(ssid) == 0) {
        reemoon_error ("无法从 %s 中提取 SSID, 退出.\n", CONF_FILE);
        free(ssid);
        return 1;
    }
    
    // 解除禁用
    if (!wifi_unblock()) {
        reemoon_error ("%s 解除禁用失败.\n", INTERFACE);
        free(ssid);
        return 1;
    }

    execute_command("ifconfig "INTERFACE" up");
    
    // 检查 wlan0 接口是否存在
    if (!interface_exists(INTERFACE)) {
        reemoon_error ("%s 接口不存在, 退出.\n", INTERFACE);
        free(ssid);
        return 1;
    }

    // 获取状态
    char status=-1;
    wifi_client_status(&status);
    reemoon_ignore ("wifi status: %d\n", status);
    if (status != 0) //wifi未连接
    {
        return 2;
    }

    // 终止 wpa_supplicant 进程
    if (execute_command("pkill wpa_supplicant") != 0) {
        reemoon_error ("Failed to kill wpa_supplicant process.\n");
    }

    // 关闭无线网卡接口
    if (execute_command("ifconfig wlan0 down") != 0) {
        reemoon_error("Failed to turn off wlan0 interface.\n");
    }

    // 阻塞 Wi-Fi 设备（可选）
    if (execute_command("rfkill block wifi") != 0) {
        reemoon_error("Failed to block Wi-Fi device.\n");
    }

    if (execute_command("killall -9 udhcpc") != 0)
    {
        reemoon_error("Failed to kill udhcpc.\n");
    }

    return 0;
}

wifi_info_t *wifi_client_status(char *status) 
{
    const char* interface = "wlan0";
    char command[BUFFER_SIZE];

    // 获取 SSID
    snprintf(command, BUFFER_SIZE, "iw %s link | grep SSID | awk '{print $2}'", INTERFACE);
    char* ssid = execute_command_get_data(command);
    if (ssid) {
        if(strstr(ssid, extract_ssid(CONF_FILE)))
        {
            memcpy (wifi_info.ssid, ssid, strlen(ssid));
            *status = 0;
            reemoon_ignore ("SSID: %s\n", ssid);
        }
        free(ssid);
    }
    else
        return NULL;

    // 获取信号强度
    /* 
        Bm 单位：dBm（分贝毫瓦）是一个用于衡量功率的单位。
        -30 dBm 到 -50 dBm：属于非常强的信号。
        -50 dBm 到 -70 dBm：属于强信号。
        -70 dBm 到 -80 dBm：属于中等信号。
        -80 dBm 到 -90 dBm：属于弱信号。
        低于 -90 dBm：属于非常弱的信号。

     */
    snprintf(command, BUFFER_SIZE, "iw %s link | grep signal | awk '{print $2}'", interface);
    char* signal = execute_command_get_data(command);
    wifi_info.signal = 256 - atoi(signal);
    if (signal) {
        if (strlen(signal) > 0)
        {
            reemoon_ignore ("Signal: %s dBm\n", signal);
        }
        free(signal);
    }

    // 获取频率 频段
    snprintf(command, BUFFER_SIZE, "iw %s link | grep freq | awk '{print $2}'", interface);
    char* freq = execute_command_get_data(command);
    wifi_info.freq = atoi(freq);
    if (freq) {
        if (strlen(freq) > 0)
        {
            reemoon_ignore ("Frequency: %s MHz\n", freq);
        }
        free(freq);
    }
    return &wifi_info;
}

void wifi_client_init(void)
{
    pthread_t rev_pth_id;
    pthread_create(&rev_pth_id, NULL, fifo_receive_pth, NULL);
    reemoon_info ("wifi client init\n");
}

int main(void)
{
    wifi_client_init();
    while (1)
    {
        usleep(10*1000);
    }
}

#include <sys/select.h>
static void *fifo_receive_pth(void *arg)
{
    fd_set read_fds;
    struct timeval timeout;
    char buffer[256];
    int bytes_read;

    // 检查管道文件是否存在
    if (access(FIFO_RX_PATH, F_OK) == 0) {
        reemoon_ignore("命名管道 %s 已存在.\n", FIFO_RX_PATH);
    }
	// 创建管道
	else if (mkfifo(FIFO_RX_PATH, 0777) == -1) {
        reemoon_error("mkfifo");
        return NULL;
    }
    // 检查管道文件是否存在
    if (access(FIFO_TX_PATH, F_OK) == 0) {
        reemoon_ignore("命名管道 %s 已存在.\n", FIFO_TX_PATH);
    }
	// 创建管道
	else if (mkfifo(FIFO_TX_PATH, 0777) == -1) {
        reemoon_error("mkfifo");
        return NULL;
    }
    // 打开命名管道（读写模式）
    fifo_rx_fd = open(FIFO_RX_PATH, O_RDONLY | O_NONBLOCK);
    if (fifo_rx_fd == -1) {
        reemoon_error("open");
        return NULL;
    }
    reemoon_ignore ("wifi app fifo_rx_fd:%d\n", fifo_rx_fd);
    fifo_tx_fd = open(FIFO_TX_PATH, O_WRONLY);
    if (fifo_tx_fd == -1) {
        reemoon_error("open");
        return NULL;
    }
    reemoon_ignore ("wifi app fifo_tx_fd:%d\n", fifo_tx_fd);
    reemoon_info ("wifi client app ready...\n");

    while (1) 
    {
        // 清空文件描述符集合
        FD_ZERO(&read_fds);
        // 将管道文件描述符加入集合
        FD_SET(fifo_rx_fd, &read_fds);

        // 设置超时时间为5秒
        timeout.tv_sec = 5;
        timeout.tv_usec = 0;

        // 使用select监听管道
        int result = select(fifo_rx_fd + 1, &read_fds, NULL, NULL, &timeout);

        if (result > 0) {  // 有数据可读
            if (FD_ISSET(fifo_rx_fd, &read_fds)) {
                bytes_read = read(fifo_rx_fd, buffer, sizeof(buffer) - 1);
                if (bytes_read > 0) {
                    buffer[bytes_read] = '\0';  // 确保字符串结尾
                    data_process(buffer, bytes_read);
                } else if (bytes_read == 0) {
                    reemoon_info ("ui_app 端关闭了管道。\n");
                    break;  // 如果对端关闭了管道，退出循环
                } else {
                    reemoon_error("read");
                }
            }
        } else if (result == 0) {  // 超时
            reemoon_ignore("超时，未接收到数据。\n");
            continue;
        } else {  // 错误
            reemoon_error("select");
            break;  // 如果发生错误，退出循环
        }
    }

    // 关闭管道
    close(fifo_rx_fd);

    reemoon_info("接收结束。\n");
    fifo_tx_fd = -1;
    wifi_client_init();
}

int wifi_client_transform(void *data, int len)
{
    if (fifo_tx_fd > 0)
    {
        int ret = write (fifo_tx_fd, data, len);
        if (ret != len)
        {
            reemoon_error ("wifi client transform failed\n");
        }
    }
}

static void data_process(char *data, int len)
{
    if (strcmp (data, WIFI_CTRL_CONNECT) == 0)
    {
        reemoon_info ("wifi connecting\n");
        if (wifi_client_connect() == 0)
        {
            reemoon_info ("wifi connected\n");
            wifi_client_transform(WIFI_CTRL_CONNECT, strlen(WIFI_CTRL_CONNECT));
            return ;
        }
        reemoon_info ("wifi to connect failed\n");
    }
    else if (strcmp (data, WIFI_CTRL_DISCONNECT) == 0)
    {
        reemoon_info ("wifi disconnecting\n");
        int ret = wifi_client_disconnect();
        if (ret == 2)
        {
            wifi_client_transform(WIFI_CTRL_DISCONNECT, strlen(WIFI_CTRL_DISCONNECT));
            reemoon_info ("wifi not connected\n");
            return ;
        }
        else if (ret == 0)
        {
            wifi_client_transform(WIFI_CTRL_DISCONNECT, strlen(WIFI_CTRL_DISCONNECT));
            reemoon_info ("wifi disconnected\n");
            return ;
        }
    }
    else if (strcmp (data, WIFI_CTRL_STATUS) == 0)
    {
        char status;
        wifi_client_status(&status) ;
        reemoon_ignore("wifi client status: %d\n", status);
        wifi_client_transform(&wifi_info, sizeof(wifi_info));
    }
}